package cz.cuni.amis.episodic.lisp;

import java.io.FileOutputStream;
import static cz.cuni.amis.episodic.lisp.LispPlanToCsvData.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import cz.cuni.amis.episodic.lisp.netcreators.CHMMCreator;
import cz.cuni.amis.episodic.lisp.netcreators.HHMMCreator;
import cz.cuni.amis.episodic.lisp.netcreators.HHMMMurphyPaskin2001Creator;
import cz.cuni.amis.episodic.lisp.netcreators.NetCreator;
import jsmile.utils.CsvToSmileData;
import lombok.Cleanup;
import smile.Network;

/**
 * Creates networks and training data from lisp plans.
 *
 * @author ik
 */
public class LispPlanResourceCreator {
    
    List<NetCreator> networkCreators;
    
    public LispPlanResourceCreator() {
        networkCreators = Arrays.asList(
                new CHMMCreator(false),
                new HHMMCreator(5, false),
                new HHMMMurphyPaskin2001Creator(5));
        
    }
    
    public static void main(String[] args) throws FileNotFoundException, IOException {
        final int hiddenNodeStatesNum = 3;
        final String outputNetworkFilename = "behan_d3.xdsl";
        final String inputLispPlan = "src/main/resources/episplanner/testdata1.lisp";
        final String outputPlanCsv = "testdata1-d3.csv";
        final NetCreator netCreator = new CHMMCreator(false);
        final int maxDepthLimit = 3;
        // size of cases used for learning and at the same time number of temporal slices
        // if it is <= 0 then maximum is used
        final int batchSize = 15;

        //processCorpus("src/main/resources/episplanner/testdata7.lisp",
        //new File("target/smile/behan"),
        //new BehanFilteredProcessor(maxDepthLimit));
        processCorpus("src/main/resources/monroe/monroe-small.txt",
                new File("target/smile/monroe"),
                0,
                new BehanFilteredProcessor(3));
    }
    
    public static void processCorpus(String inputLispPlan, File outputDirectory, int planDepth) throws FileNotFoundException, IOException {
        final int batchSize = 15;
        processCorpus(inputLispPlan, outputDirectory, batchSize, new BehanFilteredProcessor(planDepth));
    }
    
    public static void processCorpus(String inputLispPlan, File outputDirectory, int planDepth, int batchSize) throws FileNotFoundException, IOException {
        processCorpus(inputLispPlan, outputDirectory, batchSize, new BehanFilteredProcessor(planDepth));
    }

    
    /**
     * Translates LISP plan into DBNs.
     *
     * @param inputLispPlan
     * @param outputDirectory
     * @param batchSize
     * @param translator
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void processCorpus(String inputLispPlan, File outputDirectory, int batchSize, TreeToTraceTranslator translator) throws FileNotFoundException, IOException {
    new LispPlanResourceCreator().create(inputLispPlan, outputDirectory, batchSize, translator);
    }
    
    /**
     * Translates LISP plan into DBNs.
     *
     * @param inputLispPlan
     * @param outputDirectory
     * @param batchSize
     * @param translator
     * @throws FileNotFoundException
     * @throws IOException
     */
    public void create(String inputLispPlan, File outputDirectory, int batchSize, TreeToTraceTranslator translator) throws FileNotFoundException, IOException {
        outputDirectory.mkdirs();

        // get filename without path and extension
        String corporaName = new File(inputLispPlan).getName().split("\\.")[0];
        
        final int maxDepthLimit = 0;

        // read lisp to csv
        ByteArrayOutputStream csvOs = new ByteArrayOutputStream();
        LispToCsvResult res = lispToCsv(inputLispPlan, csvOs, batchSize, translator, null);
        csvOs.close();
        
        String smileDataFile = corporaName + "_smile_data.txt";
        smileDataFile = new File(outputDirectory, smileDataFile).getAbsolutePath();

        // transform csv to smile data format
        CsvToSmileData.convert(new InputStreamReader(new ByteArrayInputStream(csvOs.toByteArray())),
                smileDataFile);

        // write also the csv
        @Cleanup
        FileOutputStream fos = new FileOutputStream(new File(outputDirectory, corporaName + ".csv"));
        fos.write(csvOs.toByteArray());

        List<Network> nets = new ArrayList<>(networkCreators.size());
        
        // create network
        File chmmFile = new File(outputDirectory, corporaName + "_chmm.xdsl");
        createDBNFromCsvResult(res, new CHMMCreator(false), chmmFile.getAbsolutePath(), smileDataFile);
        
        File hhmmFile = new File(outputDirectory, corporaName + "_hhmm.xdsl");
        createDBNFromCsvResult(res, new HHMMCreator(5, false), hhmmFile.getAbsolutePath(), smileDataFile);
        
    }
}
